package com.wisdom.collect.modbus.facade;

import com.wisdom.collect.modbus.Modbus;
import com.wisdom.collect.modbus.io.AbstractModbusTransport;
import com.wisdom.collect.modbus.io.ModbusSerialTransaction;
import com.wisdom.collect.modbus.net.AbstractSerialConnection;
import com.wisdom.collect.modbus.net.SerialConnection;
import com.wisdom.collect.modbus.util.SerialParameters;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ModbusSerialMaster extends AbstractModbusMaster {

    private static final Logger logger = LoggerFactory.getLogger(ModbusSerialMaster.class);
    private AbstractSerialConnection connection;
    private int transDelay = Modbus.DEFAULT_TRANSMIT_DELAY;

    public ModbusSerialMaster(SerialParameters param) {
        this(param, Modbus.DEFAULT_TIMEOUT, Modbus.DEFAULT_TRANSMIT_DELAY);
    }

    public ModbusSerialMaster(SerialParameters param, int timeout) {
        this(param, timeout, Modbus.DEFAULT_TRANSMIT_DELAY);
    }

    public ModbusSerialMaster(SerialParameters param, int timeout, int transDelay) {
        try {
            this.transDelay = transDelay > -1 ? transDelay : Modbus.DEFAULT_TRANSMIT_DELAY;
            connection = new SerialConnection(param);
            connection.setTimeout(timeout);
            this.timeout = timeout;
        }
        catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public AbstractSerialConnection getConnection() {
        return connection;
    }

    @Override
    public void connect() throws Exception {
        if (connection != null && !connection.isOpen()) {
            connection.open();
            transaction = connection.getModbusTransport().createTransaction();
            ((ModbusSerialTransaction) transaction).setTransDelayMS(transDelay);
            setTransaction(transaction);
        }
    }

    @Override
    public void disconnect() {
        if (connection != null && connection.isOpen()) {
            connection.close();
            transaction = null;
            setTransaction(null);
        }
    }

    @Override
    public void setTimeout(int timeout) {
        super.setTimeout(timeout);
        if (connection != null) {
            connection.setTimeout(timeout);
        }
    }

    @Override
    public AbstractModbusTransport getTransport() {
        return connection == null ? null : connection.getModbusTransport();
    }
}